import { useState, useEffect, useCallback } from 'react'

interface AsyncState<T> {
  data: T | null
  error: Error | null
  loading: boolean
}

/**
 * 异步操作 Hook
 */
export function useAsync<T>(
  asyncFunction: () => Promise<T>,
  immediate = true
) {
  const [state, setState] = useState<AsyncState<T>>({
    data: null,
    error: null,
    loading: immediate
  })

  const execute = useCallback(async () => {
    setState({ data: null, error: null, loading: true })
    
    try {
      const response = await asyncFunction()
      setState({ data: response, error: null, loading: false })
      return response
    } catch (error) {
      setState({ data: null, error: error as Error, loading: false })
      throw error
    }
  }, [asyncFunction])

  useEffect(() => {
    if (immediate) {
      execute()
    }
  }, [execute, immediate])

  return { ...state, execute }
}

/**
 * 异步数据加载 Hook（带缓存）
 */
export function useAsyncData<T>(
  key: string,
  fetcher: () => Promise<T>,
  options: {
    immediate?: boolean
    cacheTime?: number
  } = {}
) {
  const { immediate = true, cacheTime = 5 * 60 * 1000 } = options
  
  const [state, setState] = useState<AsyncState<T> & { timestamp: number }>({
    data: null,
    error: null,
    loading: immediate,
    timestamp: 0
  })

  const execute = useCallback(async (force = false) => {
    // 检查缓存
    const now = Date.now()
    if (!force && state.data && now - state.timestamp < cacheTime) {
      return state.data
    }

    setState(prev => ({ ...prev, loading: true, error: null }))
    
    try {
      const response = await fetcher()
      setState({
        data: response,
        error: null,
        loading: false,
        timestamp: now
      })
      return response
    } catch (error) {
      setState(prev => ({
        ...prev,
        error: error as Error,
        loading: false
      }))
      throw error
    }
  }, [fetcher, cacheTime, state.data, state.timestamp])

  useEffect(() => {
    if (immediate) {
      execute()
    }
  }, [execute, immediate])

  return {
    data: state.data,
    error: state.error,
    loading: state.loading,
    execute,
    refresh: () => execute(true)
  }
}

